package controller

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"

	"collecter/app/cache"
	"collecter/app/common/enum"
	"collecter/app/common/helper"
	"collecter/app/model"
)

var Ctx *gin.Context
var (
	Limit int
	Page  int
)

type BaseController struct{}

/*
FormatReturn 接口统一返回函数
args []string 额外参数，只会接受并处理前面两个，多余的被忽略

	agrs[0]: 自定义返回的提示信息
	agrs[1]: 规定返回数据的格式，目前支持 json、xml、jsonp
	agrs[2]: http 状态码
*/
func (bc *BaseController) FormatReturn(errCode int, data interface{}, args ...string) {
	// 默认 json 格式
	formatName := "json"
	httpStatus := http.StatusOK

	tipMsg := helper.ReturnMsg(errCode)
	tipMsg.Data = data

	if len(args) == 1 {
		if len(args[0]) > 0 {
			tipMsg.Msg = tipMsg.Msg + ":" + args[0]
		}
	} else if len(args) == 2 {
		if len(args[0]) > 0 {
			// tipMsg["msg"] = args[0]
			tipMsg.Msg = tipMsg.Msg + ":" + args[0]
		}
		formatName = strings.ToLower(args[1])
	} else if len(args) == 3 {
		if len(args[0]) > 0 {
			// tipMsg["msg"] = args[0]
			tipMsg.Msg = tipMsg.Msg + ":" + args[0]
		}
		formatName = strings.ToLower(args[1])
		httpStatus, _ = strconv.Atoi(args[3])
	}

	switch formatName {
	case "json":
		Ctx.JSON(httpStatus, tipMsg)
	case "xml":
		Ctx.XML(httpStatus, tipMsg)
	case "jsonp":
		Ctx.JSONP(httpStatus, tipMsg)
	}
	if errCode != enum.SUCCESS {
		jsonStr, _ := json.Marshal(tipMsg)
		panic(fmt.Sprintf("%s\n", jsonStr))
	}
}

func (bc *BaseController) GetToken() string {
	headers := Ctx.Request.Header
	token := headers.Get("X-ACCESSTOKEN")
	return token
}

func (bc *BaseController) GetRefreshToken() (string, error) {
	token := bc.GetToken()
	cacheKey := enum.ACCESS_TOKEN + token
	if err := cache.Cacher.Has(cacheKey); err != nil {
		return "", errors.New("token 失效")
	}
	return cache.Cacher.GetString(cacheKey)
}

func (bc *BaseController) GetUserInfo() (*model.Users, error) {
	var user *model.Users
	var refreshToken string
	if val, err := bc.GetRefreshToken(); err != nil {
		return user, err
	} else {
		refreshToken = val
	}
	cacheKey := enum.USER_LOGIN_INFO + refreshToken
	if val, err := cache.Cacher.Get(cacheKey); err != nil {
		return user, err
	} else {
		if err := json.Unmarshal(val, &user); err != nil {
			return user, err
		}
	}
	if user.Id == 0 {
		return user, errors.New("用户缓存数据异常")
	}
	return user, nil
}

/**
*  GetHostInfo
*  @Description: 获取 host 信息，包括本机域名、端口、客户端 IP
*  @receiver this
*  @return map[string]string
 */
func (bc *BaseController) GetHostInfo() map[string]string {
	protocol := Ctx.Request.Proto
	protocols := strings.Split(protocol, "/")
	protocol = strings.ToLower(protocols[0])
	hostInfo := map[string]string{
		"domain": protocol + "://" + Ctx.Request.Host,
		// IP
		"remoteAddrIP": Ctx.RemoteIP(),
		// IP + port
		"remoteAddr": Ctx.Request.RemoteAddr,
	}
	return hostInfo
}
